home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / subs.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  17KB  |  822 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     subs.c
  5.  
  6.     DESCRIPTION
  7.     General subroutines.
  8.  
  9.     NOTES
  10.  
  11.     BUGS
  12.  
  13.     TODO
  14.  
  15.     EXAMPLES
  16.  
  17.     SEE ALSO
  18.  
  19.     INDEX
  20.  
  21.     HISTORY
  22.     16. Jan 1993    ada created
  23.  
  24. ******************************************************************************/
  25.  
  26. /**************************************
  27.         Includes
  28. **************************************/
  29. #include "defs.h"
  30. #include <clib/macros.h>
  31. #include <graphics/display.h>
  32. #define MYDEBUG     0
  33. #include "debug.h"
  34.  
  35.  
  36. /**************************************
  37.         Globale Variable
  38. **************************************/
  39. Prototype void     makemygadget     (struct Gadget *);
  40. Prototype int     firstns     (char *);
  41. Prototype int     lastns      (char *);
  42. Prototype int     wordlen     (char *);
  43. Prototype BOOL     getpathto     (BPTR, char *, char *);
  44. Prototype LINE     allocline     (long);
  45. Prototype int     detab         (char *, char *, int);
  46. Prototype int     xefgets     (FILE *, char *, int);
  47. Prototype ED   * finded      (char *, int);
  48. Prototype void     mountrequest     (int);
  49. Prototype FONT * GetFont     (char *, WORD);
  50. Prototype void     freeline     (LINE);
  51. Prototype void     movetocursor     (void);
  52. Prototype int     extend      (ED *, int);
  53. Prototype int     makeroom     (int);
  54. Prototype void     freelist     (LINE *, int);
  55. Prototype long     lineflags     (int);
  56. Prototype void     scroll_display  (WORD, WORD , Column, Line, Column, Line);
  57. Prototype char * skip_whitespace (char *);
  58. Prototype char     is_number     (char *);
  59. Prototype char * getnextcomline  (FILE *, int *);
  60. Prototype char * fname         (char *);
  61. Prototype BOOL     switch_ed     (ED *);
  62. Prototype void     do_makecursorvisible (void);
  63. Prototype void     MakeRectVisible (WIN *, UWORD, UWORD, UWORD, UWORD);
  64. Prototype int     LINELEN     (ED *, Line);
  65.  
  66. /* Assembler */
  67. Prototype void swapmem (void *, void *, ULONG);
  68.  
  69.  
  70. /**************************************
  71.       Interne Defines & Strukturen
  72. **************************************/
  73. typedef struct FileInfoBlock FIB;
  74.  
  75.  
  76. /**************************************
  77.         Interne Variable
  78. **************************************/
  79.  
  80.  
  81. /**************************************
  82.        Interne Prototypes
  83. **************************************/
  84.  
  85.  
  86. /*
  87.  *  Create XDME's text icon.
  88.  */
  89.  
  90. void makemygadget (struct Gadget *gad)
  91. {
  92.     static const UWORD ga[] =
  93.     {
  94.      /* Plane 0 */
  95.      0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0C00,
  96.      0x0000,0x0000,0x0000,0x0C00,0x0FFF,0xFFFF,0xFFFF,0x8C00,
  97.      0x0C00,0x0000,0x0000,0x0C00,0x0C1F,0xFFFF,0xFFE0,0x0C00,
  98.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x08BF,0xFFE0,0x0C00,
  99.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x25FF,0xFFE0,0x0C00,
  100.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1F,0x0BFF,0xFFE0,0x0C00,
  101.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x1FFF,0xFFE0,0x0C00,
  102.      0x0C16,0xFFFF,0xFFA0,0x0C00,0x0C1E,0x7FFF,0xFFE0,0x0C00,
  103.      0x0C17,0xFFFF,0xFFA0,0x0C00,0x0800,0x0000,0x0000,0x0C00,
  104.      0x0000,0x0000,0x0000,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  105.      0x0031,0x98CE,0x7318,0x0C00,0x001B,0x186F,0xF318,0x0C00,
  106.      0x001B,0x186F,0xF360,0x0C00,0x000E,0x186D,0xB3E0,0x0C00,
  107.      0x001B,0x186D,0xB360,0x0C00,0x001B,0x186C,0x3318,0x0C00,
  108.      0x0031,0x98CC,0x3318,0x0C00,0x007B,0xFF9E,0x7FF8,0x0C00,
  109.      0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
  110.      /* Plane 1 */
  111.      0xFFFF,0xFFFF,0xFFFF,0xF800,0xD555,0x5555,0x5555,0x5000,
  112.      0xD555,0x5555,0x5555,0x5000,0xD000,0x0000,0x0000,0x5000,
  113.      0xD000,0x0000,0x0000,0xD000,0xD000,0x0000,0x0000,0xD000,
  114.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  115.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  116.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  117.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  118.      0xD003,0xFFFF,0xFF00,0xD000,0xD003,0xFFFF,0xFF00,0xD000,
  119.      0xD003,0xFFFF,0xFF00,0xD000,0xD7FF,0xFFFF,0xFFFF,0xD000,
  120.      0xD555,0x5555,0x5555,0x5000,0xD504,0x0041,0x0005,0x5000,
  121.      0xD544,0x4511,0x0445,0x5000,0xD544,0x4510,0x0445,0x5000,
  122.      0xD544,0x4510,0x0415,0x5000,0xD551,0x4510,0x4415,0x5000,
  123.      0xD544,0x4510,0x4415,0x5000,0xD544,0x4511,0x4445,0x5000,
  124.      0xD544,0x4511,0x4445,0x5000,0xD504,0x0041,0x0005,0x5000,
  125.      0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000
  126.     };
  127.     static const struct Image image =
  128.     {
  129.      0, 0, 54, 30, 2, (UWORD *)ga, 3, 0, NULL
  130.     };
  131.  
  132.     memset (gad, 0, sizeof(struct Gadget));
  133.  
  134.     gad->Width          = 54;
  135.     gad->Height       = 31; /* Blank line between Image and Text ! */
  136.     gad->Flags          = GADGIMAGE|GADGHCOMP;
  137.     gad->GadgetType   = BOOLGADGET;
  138.     gad->Activation   = RELVERIFY|GADGIMMEDIATE;
  139.     gad->GadgetRender = (APTR)ℑ
  140. } /* makemygadget */
  141.  
  142.  
  143. /*
  144.  * return index of first non space.  Returns 0 if no spaces found.
  145.  */
  146.  
  147. int firstns (char * str)
  148. {
  149.     WORD  i;
  150.  
  151.     for (i = 0; str[i] && str[i] == ' '; i ++);
  152.  
  153.     if (str[i] == 0)
  154.     i = 0;
  155.  
  156.     return (i);
  157. } /* firstns */
  158.  
  159.  
  160. /*
  161.  *  Return index of last non-space, 0 if no spaces.
  162.  */
  163.  
  164. int lastns (char * str)
  165. {
  166.     WORD  i;
  167.  
  168.     /* get last char of string (i might be -1 after that !).
  169.        now walk left until a char != ' ' is found or i == 0. */
  170.     for (i = strlen(str) - 1; i > 0 && str[i] == ' '; i --);
  171.  
  172.     if (i < 0)  /* string empty */
  173.     i = 0;
  174.  
  175.     return (i);
  176. } /* lastns */
  177.  
  178.  
  179. /*
  180.  *  Return length of word under cursor
  181.  */
  182.  
  183. int wordlen (char * str)
  184. {
  185.     WORD  i;
  186.  
  187.     for (i = 0; *str && *str != ' '; ++i, ++str);
  188.  
  189.     return(i);
  190. } /* wordlen */
  191.  
  192.  
  193. /*
  194.  *  Backtracks the program lock, 0 on failure, 1 on success.
  195.  *  The filename is appended to the lock, if it exists.
  196.  */
  197.  
  198. BOOL getpathto (BPTR lock, char * filename, char * buf)
  199. {
  200.     if (!NameFromLock (lock, buf, PATHSIZE))
  201.     return (FALSE);
  202.  
  203.     if (filename)
  204.     AddPart (buf, filename, PATHSIZE);
  205.  
  206.     return (TRUE);
  207. }
  208.  
  209.  
  210. /*
  211.  *  Allocation routines and other shortcuts
  212.  */
  213.  
  214. static LINE empty_line = "";
  215.  
  216. LINE allocline (long size)
  217. {
  218.      if (size <= 1) return (empty_line);     /* no more tiny empty blocks */
  219.  
  220.      /* Make sure we always get a padded block */
  221.      size += 7;
  222.      size &= ~7;
  223.  
  224.      return (AllocMem (size, 0));
  225. } /* allocline */
  226.  
  227.  
  228. void freeline (LINE line)
  229. {
  230.     WORD  size;
  231.  
  232.     if (line && line != empty_line)
  233.     {
  234.     size = strlen (line) + 8;
  235.     size &= ~7;
  236.  
  237.     FreeMem (line, size);
  238.     }
  239. } /* freeline */
  240.  
  241.  
  242. /*
  243.  *  Remove tabs in a buffer
  244.  */
  245.  
  246. int detab (char * ibuf, char * obuf, int maxlen)
  247. {
  248.     WORD  i, j;
  249.  
  250.     maxlen -= 1;
  251.  
  252.     for (i = j = 0; ibuf[i] && j < maxlen; ++i)
  253.     {
  254.     if (ibuf[i] == 9)
  255.     {
  256.         do
  257.         {
  258.         obuf[j++] = ' ';
  259.         } while ((j & 7) && j < maxlen);
  260.     } else
  261.     {
  262.         obuf[j++] = ibuf[i];
  263.     }
  264.     }
  265.  
  266.     if (j && obuf[j-1] == '\n')
  267.     --j;
  268.  
  269.     while (j && obuf[j-1] == ' ')
  270.     --j;
  271.  
  272.     obuf[j] = 0;
  273.  
  274.     return (j);
  275. } /* detab */
  276.  
  277.  
  278. int xefgets (FILE * fi, char * buf, int max)
  279. {
  280.     char ebuf[MAXLINELEN];
  281.  
  282.     if (breakcheck())   /* PATCH_NULL  20-07-94 added */
  283.     return -1;    /* PATCH_NULL  20-07-94 added */
  284.  
  285.     if (fgets (ebuf, max, fi))
  286.     return (detab (ebuf, buf, max));
  287.  
  288.     return (-1);
  289. } /* xefgets */
  290.  
  291.  
  292. ED * finded (char * str, int doff)
  293.  
  294. {
  295.     ED *ed;
  296.  
  297.     for (ed = (ED *)GetHead(&DBase); ed; ed=(ED *)GetSucc((struct Node *)ed))
  298.     {
  299.     if (strlen (ed->name) >= doff && stricmp (str, ed->name+doff) == 0)
  300.         return (ed);
  301.     }
  302.  
  303.     return (NULL);
  304. } /* finded */
  305.  
  306.  
  307. void mountrequest (int bool)
  308. {
  309.     static APTR     original_pr_WindowPtr = NULL;
  310.     register PROC * proc;
  311.  
  312.     proc = (PROC *)FindTask (0);
  313.  
  314.     if (!bool && proc->pr_WindowPtr != (APTR)-1)
  315.     {
  316.     original_pr_WindowPtr = proc->pr_WindowPtr;
  317.     proc->pr_WindowPtr    = (APTR)-1;
  318.     }
  319.  
  320.     if (bool && proc->pr_WindowPtr == (APTR)-1)
  321.     proc->pr_WindowPtr = original_pr_WindowPtr;
  322. } /* mountrequest */
  323.  
  324.  
  325. /*
  326.  *  GETFONT()
  327.  *
  328.  *  This function properly searches resident and disk fonts for the
  329.  *  font.
  330.  */
  331.  
  332. struct Library * DiskfontBase;
  333.  
  334. FONT * GetFont (char * name, WORD  size)
  335. {
  336.     FONT * font1;
  337.     TA       Ta;
  338.     UWORD pos;
  339.  
  340.     strcpy (tmp_buffer, name);
  341.     pos = strlen (tmp_buffer);
  342.  
  343.     if (pos < 6 || (pos > 5 && stricmp (tmp_buffer + pos - 5, ".font")))
  344.     strcpy (tmp_buffer + pos, ".font");
  345.  
  346.     Ta.ta_Name    = (UBYTE *)tmp_buffer;
  347.     Ta.ta_YSize = size;
  348.     Ta.ta_Style = 0;
  349.     Ta.ta_Flags = 0;
  350.  
  351.     font1 = OpenFont (&Ta);
  352.  
  353.     if (!font1 || font1->tf_YSize != Ta.ta_YSize)
  354.     {
  355.     FONT * font2;
  356.  
  357.     if (DiskfontBase = OpenLibrary ("diskfont.library", 0L))
  358.     {
  359.         if (font2 = OpenDiskFont (&Ta))
  360.         {
  361.         if (font1)
  362.             CloseFont (font1);
  363.  
  364.         font1 = font2;
  365.  
  366.         CloseLibrary (DiskfontBase);
  367.         }
  368.     }
  369.     } /* if !font1 || Wrong_Font_Size */
  370.  
  371.     return (font1);
  372. } /* GetFont */
  373.  
  374.  
  375. void movetocursor (void)
  376. {
  377.     Move (Ep->win->RPort, COLT(Ep->column - Ep->topcolumn),
  378.       ROWT(Ep->line - Ep->topline));
  379. } /* movetocursor */
  380.  
  381.  
  382. int extend (ED * ep, int lines)
  383. {
  384.     long   extra = ep->maxlines - ep->lines;
  385.     LINE * list;
  386.  
  387.     if (lines > extra)
  388.     {
  389.     lines += ep->lines;
  390.  
  391.     if (list = (LINE *)alloclptr(lines))
  392.     {
  393.         bmovl (ep->list, list, ep->lines);
  394.         FreeMem (ep->list, sizeof(LINE) * ep->maxlines);
  395.  
  396.         ep->maxlines = lines;
  397.         ep->list     = list;
  398.  
  399.         return (1);
  400.     }
  401.  
  402.     nomemory ();
  403.     return (0);
  404.     }
  405.  
  406.     return (1);
  407. } /* extend */
  408.  
  409.  
  410. int makeroom (int n)
  411. {
  412.     ED * ep = Ep;
  413.  
  414.     if (ep->lines >= ep->maxlines)
  415.     return (extend (ep, n));
  416.  
  417.     return (1);
  418. } /* makeroom */
  419.  
  420.  
  421. void freelist (LINE * list, int n)
  422. {
  423.     while (n)
  424.     {
  425.     freeline (list[0]);
  426.     list ++;
  427.     n --;
  428.     }
  429. } /* freelist */
  430.  
  431.  
  432. void do_undo (void)
  433. {
  434.     text_load ();
  435.     text_redisplaycurrline ();
  436. } /* do_undo */
  437.  
  438.  
  439. long lineflags (int line)
  440. {
  441.     long flags;
  442.  
  443.     if (line < Ep->topline)
  444.     flags = LINE_ABOVE;
  445.     else if (line < Ep->topline + Lines)
  446.     flags = LINE_VISIBLE;
  447.     else
  448.     flags = LINE_BELOW;
  449.  
  450.     return (flags);
  451. } /* lineflags */
  452.  
  453.  
  454. void scroll_display (WORD  dx, WORD  dy, Column lc, Line tl, Column rc, Line bl)
  455. {
  456.     UWORD width, height;
  457.     Line lines, rest;
  458.     UWORD x1, y1, x2, y2, t;
  459.     Line bottom;
  460.     Column right;
  461.     RP * rp;
  462.  
  463.     /* don't do anything if we are not allowed */
  464.     if (Ep->iconmode || Nsu || (!dx && !dy)) return;
  465.  
  466.     /* clip coords */
  467.     if (tl < Ep->topline)
  468.     tl = Ep->topline;
  469.  
  470.     if (bl >= Ep->topline+Lines)
  471.     bl = Ep->topline + Lines - 1;
  472.  
  473.     if (lc < Ep->topcolumn)
  474.     lc = Ep->topcolumn;
  475.  
  476.     if (rc >= Ep->topcolumn+Columns)
  477.     rc = Ep->topcolumn + Columns - 1;
  478.  
  479.     /* check if area is visible */
  480.     if (bl < tl || rc < lc) return;
  481.  
  482.     /* is there something below the text */
  483.     if (bl > Ep->lines)
  484.     {
  485.     bottom = bl - Ep->lines + 1;
  486.     } else
  487.     {
  488.     bottom = 0;
  489.     }
  490.  
  491.     /* is there something to the right */
  492.     if (rc > MAXLINELEN)
  493.     {
  494.     right = rc - MAXLINELEN + 1;
  495.     } else
  496.     {
  497.     right = 0;
  498.     }
  499.  
  500.     /* get size of real text */
  501.     width  = rc - lc + 1 - right;
  502.     height = bl - tl + 1 - bottom;
  503.  
  504.     if (dx)
  505.     {
  506.     lines = ABS(dx);    /* number of columns to draw */
  507.  
  508.     if (lines >= width)
  509.          rest = 0;
  510.     else rest = width - lines;
  511.  
  512.     dx *= Xsize;
  513.     } else
  514.     {
  515.     lines = ABS(dy);    /* number of lines to draw */
  516.  
  517.     /* if the number of new lines is bigger than the height of the
  518.        remaining text, we have to erase the empty lines. Otherwise
  519.        we store the first line of the area that is to update in rest. */
  520.  
  521.     if (lines >= height)
  522.          rest = 0;
  523.     else rest = height - lines;
  524.  
  525.     dy *= Ysize;
  526.     }
  527.  
  528.     x1 = lc - Ep->topcolumn;
  529.     x2 = rc - Ep->topcolumn;
  530.     y1 = tl - Ep->topline;
  531.     y2 = bl - Ep->topline;
  532.  
  533.     t = y1;
  534.  
  535.     x1 = COL(x1);
  536.     x2 = COL(x2+1)-1;
  537.     y1 = ROW(y1);
  538.     y2 = ROW(y2+1)-1;
  539.  
  540.     rp = Ep->win->RPort;
  541.  
  542. #ifdef MYDEBUG
  543.     D(bug("scroll_display: rest %ld  height %ld  lines %ld  t %ld (%ld,%ld)-(%ld,%ld)\n",
  544.       rest, height, lines, t, x1, y1, x2, y2));
  545. #endif
  546.  
  547.     SetWrMsk (rp, 0xFF);
  548.     SetBPen (rp, TEXT_BPEN);
  549.  
  550.     if (rest)
  551.     {
  552.     ScrollRaster (rp, dx, dy, x1, y1, x2, y2);
  553.  
  554.     if (dx)
  555.     {
  556.         Line   line;
  557.         Column col;
  558.  
  559.         line = tl;
  560.         col  = lc;
  561.  
  562.         if (dx > 0)
  563.         col += rest;
  564.  
  565.         redraw_block (TRUE, line, col, line + height, col + lines - 1);
  566.     } else
  567.     {
  568.         if (dy < 0)
  569.         {
  570.         text_displayseg (t, lines);
  571.         } else
  572.         {
  573.         text_displayseg (t+rest, lines);
  574.         }
  575.     }
  576.  
  577.     if (Ep->win->WLayer->Flags & LAYERREFRESH)
  578.         OptimizedRefresh (Ep);
  579.     }
  580.     else
  581.     {
  582.     SetAPen (rp, TEXT_BPEN);
  583.     RectFill (rp, x1, y1, x2, y2);
  584.  
  585.     text_displayseg (t, height);
  586.     }
  587. } /* scroll_display */
  588.  
  589.  
  590. char * skip_whitespace (char * ptr)
  591. {
  592.     while (isspace (*ptr)) ptr ++;
  593.  
  594.     return (ptr);
  595. } /* skip_whitespace */
  596.  
  597.  
  598. /*
  599.  *  IS_NUMBER
  600.  *  tests if a string represents a valid number, i.e.
  601.  *  if there are only numbers in it ( what about spaces around,
  602.  *  and + before a number, do they disturb atol??? )
  603.  */
  604.  
  605. char is_number (char * str)           /* represents a string a number? */
  606. {
  607.     while (*str==' ')           /* ignore leading spaces */
  608.     {
  609.     str++;
  610.     } /* while */
  611.  
  612.     if ((*str=='-')||(*str=='+'))  /* dont worry about +/- */
  613.     {
  614.     str++;
  615.     } /* if */
  616.  
  617.     while (isdigit(*str))     /* if there are only numbers in str: ok */
  618.     {
  619.     str++;
  620.     } /* while */
  621.  
  622.     while (*str==' ')          /* ignore ending spaces */
  623.     {
  624.     str++;
  625.     } /* while */
  626.  
  627.     return ((char)(!*str));
  628. } /* is_number */
  629.  
  630.  
  631. char * getnextcomline (FILE* fi, int * lineno)
  632. {
  633.     /* skipps comments and emptylines */
  634.     char* buf;
  635.     char* ptr;
  636.     do
  637.     {
  638.     if (lineno)
  639.     {
  640.         (*lineno)++; /* Welches hat Priortaet?? */
  641.     } /* if */
  642.  
  643.     buf = tmp_buffer;
  644.     if ((xefgets(fi, tmp_buffer, LINE_LENGTH))<0)
  645.     /* buf = fgets(tmp_buffer, LINE_LENGTH, fi); */
  646.     if (!buf)
  647.     {
  648.         error ("%s:\nUnexpected End Of File Encountered", av[0]);
  649.         return(NULL);
  650.     } /* if */
  651.     buf[255] = 0; /* marker for eol */
  652.     while (*buf<33 && *buf)
  653.     {
  654.         buf++;
  655.     } /* while */
  656.     } while (buf[0] == 0 || buf[0] == '#');
  657.     for (ptr = buf; *ptr;ptr++)
  658.     {
  659.     if (*ptr == 10)
  660.     {
  661.         *ptr = 0;
  662.     } /* if */
  663.     } /* for */
  664.     return(buf);
  665. } /* getnextcomline */
  666.  
  667.  
  668. /*
  669.  *  fname
  670.  *
  671.  *  instead of a macro: sets a ptr to the filename of a full path&filename
  672.  *  (returniert einen Zeiger auf den namensteil eines pfades)
  673.  *
  674.  * SHOULD BE PUT INTO SUBS.C
  675.  */
  676.  
  677. char * fname (char * fullpath)
  678. {
  679.     return ((char *)FilePart (fullpath));
  680. } /* fname */
  681.  
  682.  
  683. BOOL switch_ed (ED * newed)
  684. {
  685.     BOOL success;
  686.  
  687.     if (newed)
  688.     {
  689.     if (Ep)
  690.         text_sync ();
  691.  
  692.     Ep = newed;
  693.  
  694.     text_load ();
  695.  
  696.     if (!Ep->iconmode)
  697.     {
  698.         set_window_params ();
  699.         window_title ();
  700.     }
  701.  
  702.     text_cursor (1);
  703.  
  704.     success = TRUE;
  705.     } else
  706.     success = FALSE;
  707.  
  708.     return (success);
  709. } /* switch_ed */
  710.  
  711.  
  712. void do_makecursorvisible (void)
  713. {
  714.     if ((Ep->win->Flags & WFLG_WINDOWACTIVE) && !Ep->iconmode)
  715.     {
  716.     UWORD x1 = COL(Ep->column - Ep->topcolumn) + Ep->win->LeftEdge;
  717.     UWORD y1 = ROW(Ep->line   - Ep->topline)   + Ep->win->TopEdge;
  718.     UWORD x2, y2;
  719.  
  720.     x2 = x1 + (Xsize << 2) + Xsize;
  721.     y2 = y1 + (Ysize << 2) + Ysize;
  722.  
  723.     if (x1 < (Xsize << 2))
  724.         x1 = 0;
  725.     else
  726.         x1 -= Xsize << 2;
  727.  
  728.     if (y1 < (Ysize << 2))
  729.         y1 = 0;
  730.     else
  731.         y1 -= Ysize << 2;
  732.  
  733.     MakeRectVisible (Ep->win, x1, y1, x2, y2);
  734.     }
  735. } /* do_makecursorvisible */
  736.  
  737.  
  738. void MakeRectVisible (WIN * win, UWORD minx, UWORD miny, UWORD maxx, UWORD maxy)
  739. {
  740.     struct DimensionInfo diminfo;
  741.     struct Screen      * screen        = win->WScreen;
  742.     ULONG         Width, Height;
  743.     WORD         dx, dy;
  744.  
  745.     GetDisplayInfoData (NULL,
  746.             (UBYTE *)&diminfo,
  747.             sizeof(diminfo),
  748.             DTAG_DIMS,
  749.             GetVPModeID (&screen->ViewPort)
  750.     );
  751.  
  752.     Width  = diminfo.TxtOScan.MaxX - diminfo.TxtOScan.MinX;
  753.     Height = diminfo.TxtOScan.MaxY - diminfo.TxtOScan.MinY;
  754.  
  755.     if (Width > screen->Width)
  756.     Width = screen->Width;
  757.  
  758.     if (Height > screen->Height)
  759.     Height = screen->Height;
  760.  
  761.     if (minx < win->LeftEdge)
  762.     minx = win->LeftEdge;
  763.  
  764.     if (miny < win->TopEdge)
  765.     miny = win->TopEdge;
  766.  
  767.     if (maxx > win->LeftEdge + win->Width)
  768.     maxx = win->LeftEdge + win->Width;
  769.  
  770.     if (maxy > win->TopEdge + win->Height)
  771.     maxy = win->TopEdge + win->Height;
  772.  
  773.     dx = (Width - screen->LeftEdge) - maxx + 1;
  774.  
  775.     if (dx > 0)
  776.     {
  777.     dx = minx + screen->LeftEdge;
  778.  
  779.     if (dx > 0)
  780.         dx = 0;
  781.     else
  782.         dx = -dx;
  783.     }
  784.  
  785.     dy = (Height - screen->TopEdge) - maxy + 1;
  786.  
  787.     if (dy > 0)
  788.     {
  789.     dy = miny + screen->TopEdge;
  790.  
  791.     if (dy >= 0)
  792.         dy = 0;
  793.     else
  794.         dy = -dy;
  795.     }
  796.  
  797.     MoveScreen (screen, dx, dy);
  798. } /* MakeRectVisible */
  799.  
  800.  
  801. int LINELEN (ED * ep, Line nr)
  802. {
  803.     int len;
  804.  
  805.     if (nr == ep->line)
  806.     {
  807.     /* line is in Current */
  808.  
  809.     if ((len = lastns ((char *)Current)) || (*Current && *Current != ' '))
  810.         len ++;
  811.     }
  812.     else
  813.     len = strlen (GETTEXT(ep,nr));
  814.  
  815.     return (len);
  816. } /* LINELEN */
  817.  
  818.  
  819. /******************************************************************************
  820. *****  ENDE subs.c
  821. ******************************************************************************/
  822.